
#ifndef _TTG_EXTRAS_SERIALIZATION_DESERIALIZER_
#define _TTG_EXTRAS_SERIALIZATION_DESERIALIZER_
#include "Common/Definitions.h"

#include <string>
#include "Common/Structures.h"

namespace ttg
{
	namespace extras
	{
		namespace serialization
		{
			class DeSerializer
			{
				protected:
					//Deserializes memory part.
					//Optionally, checks correctness of "size" and "name".
					//Note: in case of error throws ttg::Error().
					virtual void deserializeMemory(void *data, size_t size, const char *name) = 0;
					//Deserializes start of reference.
					//Optionally, checks correctness of "size" and "name".
					//Note: in case of error throws ttg::Error().
					virtual void deserializeReferenceStart(bool &is_null, const char *name) = 0;
					//Deserializes end of reference.
					//Optionally, checks correctness of "size" and "name".
					//Note: in case of error throws ttg::Error().
					virtual void deserializeReferenceEnd(const char *name) = 0;
				public:
					//Deserializes int value.
					//Optionally, checks correctness of "name".
					inline void deserializeInt(__int32 &value, const char *name)
					{ deserializeMemory(&value, sizeof(__int32), name); }
					//Deserializes bool value.
					//Optionally, checks correctness of "name".
					inline void deserializeBool(bool &value, const char *name)
					{ deserializeMemory(&value, sizeof(bool), name); }
					//Deserializes float value.
					//Optionally, checks correctness of "name".
					inline void deserializeFloat(float &value, const char *name)
					{ deserializeMemory(&value, sizeof(float), name); }
					//Deserializes double value.
					//Optionally, checks correctness of "name".
					inline void deserializeDouble(double &value, const char *name)
					{ deserializeMemory(&value, sizeof(double), name); }
					//Deserializes std::string value.
					//Optionally, checks correctness of "name".
					void deserializeString(std::string &value, const char *name);
					//Reconfigures object according to serialized representation.
					//Optionally, checks correctness of "name".
					//Note: "object" cannot be equal to NULL.
					//Note: But it can be released and assigned to NULL.
					template <class T>
					void deserializeObject(T *&object, const char *name)
					{
						ttg::structures::SerializableObject *ref = object;
						if (ref == NULL)
							throw ttg::Error(ttg::Error::FATAL, "ByteDeSerializer", "deserializeObject",
											 "Deserialized cannot be equal to NULL");
						if (!deserializeObject(*ref, name))
							SAFE_DELETE(object);
					}
					//Reconfigures object according to serialized representation.
					//Optionally, checks correctness of "name".
					//Returns false, if loaded object should be assigned to NULL.
					bool deserializeObject(structures::SerializableObject &object, const char *name);
			};
		}
	}
}

#endif
